/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package db.JDBC.core;

import core.*;
import core.comparators.ComparatorFactory;
import core.comparators.UserComparator.USERCOMPARATORTYPE;
import db.JDBC.*;
import db.core.interfaces.UserDAOCore;
import db.interfaces.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
/**
 *
 * @author Anton
 */
public class UserJdbcDAOCore implements UserDAOCore
{
    private static UserJdbcDAOCore instance = null;
    private UserDAO userDAO;
    private ProgramDAO programDAO;
    private CourseDAO courseDAO;
    private CRUDJdbcDAOCore crud;

    /**
     * 
     */
    private UserJdbcDAOCore()
    {
        JdbcDaoFactory daoFactory = JdbcDaoFactory.getInstance();
        userDAO = daoFactory.getUserJdbcDAO();
        programDAO = daoFactory.getProgramJdbcDao();
        courseDAO = daoFactory.getCourseJdbcDao();
        crud = CRUDJdbcDAOCore.getInstance();
    }

    /**
     * 
     * @return
     */
    public static UserJdbcDAOCore getInstance()
    {
        if(instance == null)
            instance = new UserJdbcDAOCore();
        return instance;
    }

    /**
     * 
     * @param id
     * @return
     */
    public User getUserByUserId(long id)
    {
        return crud.getUser(id);
    }
    /**
     * 
     * @param email
     * @return
     */
    public User getUserByEmail(String email)
    {
        if(email == null)
            return null;
        long id = userDAO.getUserByEmail(email).getId();
        return crud.getUser(id);
    }

    /**
     * 
     * @param beginsWith
     * @param maxResult
     * @return
     */
    public Collection<String> searchForStringUsers(String beginsWith, int maxResult)
    {
        Collection<User> emails = userDAO.searchForUsersByEmail(beginsWith);
        Collection<User> fnames = userDAO.searchForUsersByFName(beginsWith);
        Collection<User> lnames = userDAO.searchForUsersByLName(beginsWith);
        Collection<String> t = new TreeSet<String>();
        List<String> returnCollection = new ArrayList<String>();
        
        if(emails != null)
            for(User u : emails)
                if(u != null)
                    t.add(u.getEmail());
        if(fnames != null)
            for(User u : fnames)
                if(u != null)
                    t.add(u.getFname());
        if(lnames != null)
            for(User u : lnames)
                if(u != null)
                    t.add(u.getLname());
        
        for(String s : t)
            if(s != null)
                returnCollection.add(s);
        
        if(returnCollection.size() < maxResult)
            maxResult = returnCollection.size();
        return returnCollection.subList(0, maxResult);
    }
    /**
     * 
     * @param beginsWith
     * @return
     */
    public Collection<User> searchForObjectUsers(String beginsWith)
    {
        Collection<User> emails = userDAO.searchForUsersByEmail(beginsWith);
        Collection<User> fnames = userDAO.searchForUsersByFName(beginsWith);
        Collection<User> lnames = userDAO.searchForUsersByLName(beginsWith);
        Collection<User> t = new TreeSet<User>(ComparatorFactory.getUserComparator(USERCOMPARATORTYPE.ID, true));
        List<User> returnCollection = new ArrayList<User>();
        
        if(emails != null)
            for(User u : emails)
                if(u != null)
                    t.add(u);
        if(fnames != null)
            for(User u : fnames)
                if(u != null)
                    t.add(u);
        if(lnames != null)
            for(User u : lnames)
                if(u != null)
                    t.add(u);
        for(User u : t)
            if(u != null)
                returnCollection.add(u);
        Collections.sort(returnCollection,ComparatorFactory.getUserComparator(USERCOMPARATORTYPE.FIRSTNAME, true));

        return returnCollection;
    }

    /**
     * 
     * @param fname
     * @return
     */
    public Collection<User> getUsersByFName(String fname)
    {
        if(fname == null)
            return null;
        Collection<User> users = new ArrayList<User>();
        for(User u : userDAO.getUsersByFName(fname))
            if(u != null)
                users.add(crud.getUser(u.getId()));        
        return users;        
    }
    /**
     * 
     * @param lname
     * @return
     */
    public Collection<User> getUsersByLName(String lname)
    {
        if(lname == null)
            return null;
        Collection<User> users = new ArrayList<User>();
        for(User u : userDAO.getUsersByFName(lname))
            if(u != null)
                users.add(crud.getUser(u.getId()));
        return users;        
    }
    /**
     * 
     * @return
     */
    public Collection<User> getAllUsers()
    {
        Collection<User> users = new ArrayList<User>();
        for(User u : userDAO.getAllUsers())
            if(u != null)
                users.add(crud.getUser(u.getId()));
        return users;        
    }
    /**
     * 
     * @param user
     * @param program
     */
    public void addProgramToUser(User user, Program program)
    {
        if(user == null || program == null)
            return;
        if(!programDAO.containsProgram(program))
            return;
        userDAO.addProgramToUser(user, program);
        user.addProgram(program);
    }
    /**
     * 
     * @param user
     * @param program
     */
    public void deleteProgramFromUser(User user, Program program)
    {
        if(user == null || program == null)
            return; 
        userDAO.deleteProgramFromUser(user, program);
        user.removeProgram(program);
    }

    /**
     * 
     * @param user
     * @param course
     */
    public void addCourseToUser(User user, Course course)
    {
        if(user == null || course == null)
            return;
        if(!courseDAO.containsCourse(course))
            return;
        userDAO.addCourseToUser(user, course);
        user.addCourse(course);
    }
    /**
     * 
     * @param user
     * @param course
     */
    public void deleteCourseFromUser(User user, Course course)
    {
        if(user == null || course == null)
            return;
        userDAO.deleteCourseFromUser(user, course);
        user.removeCourse(course);
    }

    /**
     * 
     * @param user
     */
    public void addUser(User user)
    {
        if(user == null)
            return;
        crud.addUser(user);
    }
    /**
     * 
     * @param user
     */
    public void updateUser(User user)
    {
        if(user == null)
            return;
        crud.updateUser(user);
    }
    /**
     * 
     * @param user
     */
    public void deleteUser(User user)
    {
        if(user == null)
            return;
        crud.deleteUser(user);
    }
}
